﻿using Endos.Wodo.Web;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Syntax;
using Ninject.Web.Common;
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;

[assembly: WebActivator.PreApplicationStartMethod(typeof(NinjectConfig), "Start")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(NinjectConfig), "Stop")]

namespace Endos.Wodo.Web
{
    public static class NinjectConfig
    {
        private static readonly Bootstrapper bootstrapper;

        static NinjectConfig()
        {
            bootstrapper = new Bootstrapper();
        }

        public static void Start()
        {
            DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
            DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
            bootstrapper.Initialize(CreateKernel);
            DependencyResolver.SetResolver(new NinjectDependencyResolver(bootstrapper.Kernel));
        }

        public static void Stop()
        {
            bootstrapper.ShutDown();
        }

        private static IKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => bootstrapper.Kernel);
            kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
            kernel.Load(new Web.Hubs.Module());
            kernel.Load(new Business.Module());
            kernel.Load(new Persistence.Module());
            return kernel;
        }

        public static T Get<T>()
        {
            return bootstrapper.Kernel.Get<T>();
        }

        private class NinjectDependencyResolver : IDependencyResolver
        {
            private readonly IResolutionRoot resolutionRoot;

            public NinjectDependencyResolver(IResolutionRoot resolutionRoot)
            {
                this.resolutionRoot = resolutionRoot;
            }

            public object GetService(Type serviceType)
            {
                return resolutionRoot.TryGet(serviceType);
            }

            public IEnumerable<object> GetServices(Type serviceType)
            {
                return resolutionRoot.GetAll(serviceType);
            }
        }
    }
}